package com.wenxin.springbootcacheconsistency.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenxin.springbootcacheconsistency.domain.Goods;
import com.wenxin.springbootcacheconsistency.mapper.GoodsMapper;
import com.wenxin.springbootcacheconsistency.service.GoodsService;
import com.wenxin.springbootcacheconsistency.service.OrderService;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
* @author Administrator
* @description 针对表【goods】的数据库操作Service实现
* @createDate 2024-12-25 15:35:14
*/
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods>
    implements GoodsService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OrderService orderService;
    @Override
    public Boolean reduceGoodsStock(Long goodsId, Long stock) {
        RLock rLock = redissonClient.getReadWriteLock("goods_stock_" + goodsId).writeLock();

        try {
            if (rLock.tryLock(2, 5, TimeUnit.SECONDS)){
                Goods goods = getById(goodsId);
                Long stock1 = goods.getStock();
                if (stock > stock1){
                    throw new RuntimeException("库存不足");
                }
                stock1 = stock1 - stock;
                goods.setStock(stock1);
                orderService.createOrder(goodsId, stock);
                updateById(goods);
                redisTemplate.opsForHash().put("good_stock", String.valueOf(goodsId), stock1);
                return true;
            } else {
                throw new RuntimeException("操作频繁,请重试");
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if (rLock.isHeldByCurrentThread()){
                rLock.unlock();
            }
        }

    }
}




